/*
 -- IOTA Crypto Core
 --
 -- 2018 by Thomas Pototschnig <microengineer18@gmail.com>
 -- discord: pmaxuw#8292
 -- https://gitlab.com/iccfpga-rv
 --
 -- Permission is hereby granted, free of charge, to any person obtaining
 -- a copy of this software and associated documentation files (the
 -- "Software"), to deal in the Software without restriction, including
 -- without limitation the rights to use, copy, modify, merge, publish,
 -- distribute, sublicense, and/or sell copies of the Software, and to
 -- permit persons to whom the Software is furnished to do so, subject to
 -- the following conditions:
 --
 -- The above copyright notice and this permission notice shall be
 -- included in all copies or substantial portions of the Software.
 --
 -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 -- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 -- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 -- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 -- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 -- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWAR
 */


#include "api/API.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "main.h"

#include "micro-os-plus/diag/trace.h"
#include "xil_printf.h"

extern API::apiFlagsStruct apiFlags;

char debugPrintfBuf[256]={0};

#define max(a,b) (a>b)?a:b
#define min(a,b) (a<b)?a:b

void debugPrintHex(uint8_t* data, int size, int b) {
	int chunks = size / b;
	if (size % b) {
		chunks++;
	}
	for (int i=0;i<chunks;i++) {
		int idx = 0;
		int chunk = min(size, b);
		for (int j=0;j<chunk;j++) {
			idx += snprintf(&debugPrintfBuf[idx], max(0, (int) sizeof(debugPrintfBuf) - idx), "0x%02x ", *data++);
		}
//		if (apiFlags.debugSemihostingOutput) {
//			trace_printf("%s\n", debugPrintfBuf);
//		}
//		if (apiFlags.debugRS232Output) {
			xil_printf("%s\r\n", debugPrintfBuf);
//		}
		size -= chunk;
	}

}

void debugPrintf(const char *format, ...) {
#ifdef DEBUG
	if (!apiFlags.debugSemihostingOutput && !apiFlags.debugRS232Output)
		return;



	// this takes a lot of memory space - perhaps only use it optional
	// passing format and ap to trace_printf and xil_printf caused corrupt output ...
	va_list ap;
	va_start (ap, format);
	vsnprintf(debugPrintfBuf, sizeof(debugPrintfBuf)-3, format, ap);
	va_end (ap);

	int len = strlen(debugPrintfBuf);
	if ((len - 1) >= 0) {
		char* p = &debugPrintfBuf[len]-1;

		if (*p == '\n') {
			*p++ = '\r';
			*p++ = '\n';
			*p = 0;
		}
	}
	if (apiFlags.debugSemihostingOutput) {
		trace_printf("%s", debugPrintfBuf);
	}
	if (apiFlags.debugRS232Output) {
		xil_printf("%s", debugPrintfBuf);
	}
#endif
}


